package com.tgy.JUC.FinalLock;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/***
 * @ClassName: ReentrantTest
 * @Description: 测试可重入锁
 * @Auther: 送你一块二向箔
 * @Date: 16:23 2022/3/16
 * @version : V1.0
 */
public class ReentrantTest {
    public static void main(String[] args) {
        run2();
    }

    public static void run1() {
        Phone phone = new Phone();
        new Thread(() -> {
            phone.call();
            try {
                TimeUnit.SECONDS.sleep(0);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, "线程一").start();
        new Thread(() -> {
            phone.sms();
        }, "线程二").start();
    }

    public static void run2() {
        Phone2 phone = new Phone2();
        new Thread(() -> {
            phone.call();
            try {
                TimeUnit.SECONDS.sleep(0);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, "线程一").start();
        new Thread(() -> {
            phone.sms();
        }, "线程二").start();
    }


}

class Phone {
    public synchronized void call() {
        System.out.println(Thread.currentThread().getName() + "   call");
        try {
            TimeUnit.SECONDS.sleep(5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        sms();//这里也有锁
    }

    public synchronized void sms() {
        System.out.println(Thread.currentThread().getName() + "   sms");
    }
}

class Phone2 {
    private ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock();
    Lock lock = reentrantReadWriteLock.writeLock();


    public void call() {
        lock.lock();//解锁开锁必须配对
        try {
            System.out.println(Thread.currentThread().getName() + "   call");
            TimeUnit.SECONDS.sleep(4);
            sms();//这里也有锁
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public void sms() {
        lock.lock();
        try {
            System.out.println(Thread.currentThread().getName() + "   sms");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
}
